import {
	Injectable,
	NotFoundException,
	BadRequestException,
	Logger,
} from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { Address } from "./entities/address.entity";
import { CreateAddressDto } from "./dto/create-address.dto";
import { UpdateAddressDto } from "./dto/update-address.dto";

@Injectable()
export class AddressService {
	private readonly logger = new Logger(AddressService.name);

	constructor(
		@InjectRepository(Address)
		private addressRepository: Repository<Address>
	) {}

	async create(createAddressDto: CreateAddressDto): Promise<Address> {
		const newAddress = this.addressRepository.create(createAddressDto);

		// 如果设置为默认地址，需要将该用户的其他地址设为非默认
		if (newAddress.isDefault) {
			await this.resetDefaultAddress(newAddress.userId);
		}

		return this.addressRepository.save(newAddress);
	}

	async findAll(userId: number): Promise<Address[]> {
		return this.addressRepository.find({
			where: { userId },
			order: { isDefault: "DESC", createdAt: "DESC" },
		});
	}

	async findOne(id: number, userId?: number): Promise<Address> {
		const address = await this.addressRepository.findOne({ where: { id } });

		if (!address) {
			throw new NotFoundException(`地址ID为${id}的地址不存在`);
		}

		// 如果提供了userId，验证地址是否属于该用户
		if (userId !== undefined && address.userId !== userId) {
			throw new BadRequestException("无权查看此地址");
		}

		return address;
	}

	async update(
		id: number,
		updateAddressDto: UpdateAddressDto,
		userId?: number
	): Promise<Address> {
		const address = await this.findOne(id);

		// 如果提供了userId，验证地址是否属于该用户
		if (userId !== undefined && address.userId !== userId) {
			throw new BadRequestException("无权修改此地址");
		}

		// 合并更新数据
		const updatedAddress = { ...address, ...updateAddressDto };

		// 如果设置为默认地址，需要将该用户的其他地址设为非默认
		if (updatedAddress.isDefault) {
			await this.resetDefaultAddress(updatedAddress.userId);
		}

		return this.addressRepository.save(updatedAddress);
	}

	async remove(id: number, userId?: number): Promise<void> {
		const address = await this.findOne(id);

		// 如果提供了userId，验证地址是否属于该用户
		if (userId !== undefined && address.userId !== userId) {
			throw new BadRequestException("无权删除此地址");
		}

		await this.addressRepository.remove(address);
	}

	async setDefault(id: number, userId: number): Promise<Address> {
		const address = await this.findOne(id);

		// 验证地址是否属于该用户
		if (address.userId !== userId) {
			throw new BadRequestException("无权操作此地址");
		}

		// 重置该用户的其他地址为非默认
		await this.resetDefaultAddress(userId);

		// 设置当前地址为默认
		address.isDefault = true;
		return this.addressRepository.save(address);
	}

	private async resetDefaultAddress(userId: number): Promise<void> {
		await this.addressRepository.update(
			{ userId, isDefault: true },
			{ isDefault: false }
		);
	}
}
